#pragma once

#include <vector>
#include <iostream>

#include "Structs.h"
#include "Utils.h"
#include "LidarConfigurationOptions.h"

#ifdef _WIN32
//#include <winsock.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#endif // !M_PI

#include <rs_driver/api/lidar_driver.hpp>
#include <rs_driver/msg/pcl_point_cloud_msg.hpp>
#include <pcl/point_types.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <Poco/Thread.h>

class LidarDriverX
{
public:
    LidarDriverX(LidarConfigurationOptions *options = new LidarConfigurationOptions(), int id = 0);
    ~LidarDriverX();

    void start();
    void stop();

    /// @brief 添加回调--数据接收
    /// @param callback
    bool addPointCloudMsgCallback(PointCloudDataCallback callback);

protected:
    int _lidar_id;

    LidarConfigurationOptions *_options;
    std::vector<PointCloudDataCallback> _pointCloudDataCallback;

    LidarDecodeType _decodeType;
    TransformParam _transformParam;
    bool is_noDelay = false;
    int max_buffer_num = 8;
    float filt_meank = 50.0f, filt_threshold = 1.0f;
    float sample_voxel_size = 0.01f;

    bool _to_exit_process;
    Poco::Thread _threadPointCloudProcess;
    static void threadPointCloudProcess(void *pContext);

    void updateDriverParam(LidarConfigurationOptions *_options);
    void decodePointCloud(PointCloudData<pcl::PointXYZI> &data, pcl::PointCloud<pcl::PointXYZI>::Ptr pcl_pointcloud);

protected:
    virtual void init() = 0;
    virtual void dispose() = 0;
    virtual void processPointCloud() = 0;
};